# -*- coding: utf-8 -*-
# Powered By: KC
# @Time : 2020/4/19 11:34
import os
import threading
import time
import traceback

from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction

from common.logger import logger
from inter.commonKeys import sysKey


class APP:
    """
    app自动化关键字库
    """
    def __init__(self,writer):
        """
        初始化实例变量
        :param writer:
        """
        self.writer = writer
        self.row = 0
        self.conf = {} #保存appium和app的配置
        self.driver = None
        self.e = None

    def startappium(self,port=""):
        if port == "":
            port = "4723"

        self.conf["port"] = port
        def runappium(port="4723"):
            """
            启动appium
            :param port:
            :return:
            """
            cmd = r"appium -a 127.0.0.1 -p " + port
            #阻塞
            res = os.popen(cmd).read()
            logger.info(res)

        #创建一个子线程
        th = threading.Thread(target=runappium,args=())
        #启动线程
        th.start()
        time.sleep(5)
        self.__write_excel(True,"等待成功")
        logger.info("创建子线程")

    def stopappium(self,port=""):
        if port == "":
            port = "4723"
        try:
            pid = os.popen("netstat -aon | findstr LISTENING | findstr " + port).read()
            pid = pid.split(" ")
            if len(pid) < 2:
                return
            else:
                pid = pid[len(pid)-1]

            res = os.popen("taskkill /F /PID " + pid).read()
            logger.info(res)
        except  Exception as e:
            pass

    def startapp(self,conf):
        """
        启动app
        :param conf:{
                      "platformName": "Android",
                      "platformVersion": "5.1.1",
                      "deviceName": "127.0.0.1:62001",
                      "appPackage": "com.tencent.mm",
                      "appActivity": ".ui.LauncherUI",
                      "noReset": True,
                      "unicodeKeyboard": True,
                      "resetKeyboard": True,
                      "automationName": "UiAutomator1"
                    }
        :return:
         "automationName": "UiAutomator1"  这个用来测试小程序
        """
        try:
            conf = conf.replace(r"\n","")
            conf = eval(conf)
            logger.info(conf)
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            self.writer.save_close()
            self.stopappium(self.conf["port"])
            exit(-1)
            return False
        try:
            self.conf.update(conf)
            self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",conf)
            self.driver.implicitly_wait(20)
            self.__write_excel(True,"打开app成功")
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            self.writer.save_close()
            logger.info("启动app失败")
            self.stopappium(self.conf["port"])
            exit(-1)
            return  False

    def sleep(self,t):
        """
        固定等待
        :param t:
        :return:
        """
        try:
            time.sleep(int(t))
            self.__write_excel(True,"等待")
            return True
        except Exception as e :
            self.__write_excel(False,traceback.format_exc())
            return False

    def waitele(self,locator):
        """
        使用隐式等待 等待元素出现
        :param locator:
        :return:
        """
        ele = self.__find_ele(locator)
        if ele is None:
            self.__write_excel(False,"等待失败")
        else:
            self.__write_excel(True,"等待成功")

    def slide(self,p1,p2):
        """
        滑动
        :param p1:这里传起始滑动的坐标元组或者列表
        :param p2:传滑向的坐标元组或者列表
        :return:
        """
        try:
            p1 = p1.split(",")
            p2 = p2.split(",")
            #滑动
            TouchAction(self.driver).press(x=int(p1[0]), y=int(p1[1])).move_to(x=int(p2[0]),
                                                                               y=int(p2[1])).release().perform()
            self.__write_excel(True,"滑动成功")
            return  True
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            return False

    def input(self,locator,text,t=""):
        """
        定位元素 输入文本
        :param locator:
        :param text:
        :param t:固定等待时间
        :return:
        """
        if t == "":
            t = 10
        time.sleep(int(t))

        ele = self.__find_ele(locator)
        if ele is None:
            self.__write_excel(False,"定位元素失败")
            return False
        try:
            text = self.__get_relations(text)
            ele.send_keys(text)
            self.__write_excel(True,"输入成功")
            return True
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            return False

    def gettext(self,locator,param="text",t=""):
        """
        获取元素文本 并且保存为关联后参数名字 param
        :param locator:
        :param param:
        :param t: 等待时间
        :return:
        """
        if t == "":
            t = 10
        time.sleep(int(t))

        ele = self.__find_ele(locator)
        if ele is None:
            self.__write_excel(False,self.e)
            return False

        try:
            text = ele.text
            sysKey.relations[param] = text
            self.__write_excel(True,"获取元素文本成功")
            return True
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            return False

    def assertcontains(self,expect,actual):
        """
        断言关键字
        :param expect:期望结果
        :param actual: 实际记过
        :return:
        """
        actual = self.__get_relations(actual)
        expect = self.__get_relations(expect)

        if actual.__contains__(str(expect)):
            self.__write_excel(True,actual)
            return True
        else:
            self.__write_excel(False,actual)
            return False

    def click(self,locator,t=""):
        """
        点击元素
        :param locator:
        :return:
        """
        if t == '':
            t = 10
        time.sleep(int(t))

        ele = self.__find_ele(locator)
        if ele is None:
            self.__write_excel(False, self.e)
            return False
        try:
            ele.click()
            self.__write_excel(True, "点击成功")
            return True
        except Exception as e:
            self.__write_excel(False, traceback.format_exc())
            return False

    def adbclick(self,x,y,t=""):
        """
        通过adb完成坐标点击
        :param x:
        :param y:
        :param t: 等待时间
        :return:
        """
        if t == "":
            t = 10
        time.sleep(int(t))

        try:
            logger.info("adb shell input tap %s %s" %(x,y))
            os.popen("adb shell input tap %s %s"%(x,y)).read()
            self.__write_excel(True,"adb点击成功")
            return True
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            return False

    def quit(self):
        """
        退出app
        :return:
        """
        try:
            self.driver.quit()
            self.__write_excel(True,"退出成功")
            return True
        except Exception as e:
            self.__write_excel(False,traceback.format_exc())
            return False



    def __write_excel(self,status,msg):
        """
        在表格里面写入关键字运行结果
        :param status: 状态
        :param msg: 结果信息
        :return:
        """
        if status == True:
            self.writer.write(self.row,7,"PASS",3)
        else:
            self.writer.write(self.row,7,"FAIL",2)

        msg = str(msg)
        if len(msg) > 32767:
            msg = msg[0:32767]
        self.writer.write(self.row,8,msg)

    def __find_ele(self,locator):
        """
        通过定位器找到元素
        :param locator:
        :return:
        """
        try:
            if locator.startswith("/"):
                ele = self.driver.find_element_by_xpath(locator)
            elif locator.index(":id/") > 0:
                ele = self.driver.find_element_by_id(locator)
            else:
                ele = self.driver.find_element_by_accessibility_id(locator)
        except Exception as e:
            self.e = traceback.format_exc()
            return  None

    def __get_relations(self,params):
        """
        使用关联结果
        :param params:需要关联的参数
        :return: 关联后的字符
        """
        if params is None:
            return  None
        else:
            params = str(params)

        for key in sysKey.relations.keys():
            params = params.replace("{" + key + "}",str(sysKey.relations[key]) )
            return params


